home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / lisp / wgdb-42.lha / wgdb-4.2 / gdb / expprint.c < prev    next >
C/C++ Source or Header  |  1992-09-11  |  12KB  |  403 lines

  1. /* Print in infix form a struct expression.
  2.    Copyright (C) 1986, 1989, 1991 Free Software Foundation, Inc.
  3.  
  4. This file is part of GDB.
  5.  
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include <stdio.h>
  21. #include "defs.h"
  22. #include "symtab.h"
  23. #include "param.h"
  24. #include "expression.h"
  25. #include "value.h"
  26. #include "language.h"
  27. #include "parser-defs.h"
  28.  
  29. static void print_simple_m2_func();
  30. static void print_subexp ();
  31.  
  32. void
  33. print_expression (exp, stream)
  34.      struct expression *exp;
  35.      FILE *stream;
  36. {
  37.   int pc = 0;
  38.   print_subexp (exp, &pc, stream, PREC_NULL);
  39. }
  40.  
  41. /* Print the subexpression of EXP that starts in position POS, on STREAM.
  42.    PREC is the precedence of the surrounding operator;
  43.    if the precedence of the main operator of this subexpression is less,
  44.    parentheses are needed here.  */
  45.  
  46. static void
  47. print_subexp (exp, pos, stream, prec)
  48.      register struct expression *exp;
  49.      register int *pos;
  50.      FILE *stream;
  51.      enum precedence prec;
  52. {
  53.   register unsigned tem;
  54.   register const struct op_print *op_print_tab;
  55.   register int pc;
  56.   unsigned nargs;
  57.   register char *op_str;
  58.   int assign_modify = 0;
  59.   enum exp_opcode opcode;
  60.   enum precedence myprec;
  61.   /* Set to 1 for a right-associative operator.  */
  62.   int assoc;
  63.   value val;
  64.  
  65.   op_print_tab = exp->language_defn->la_op_print_tab;
  66.   pc = (*pos)++;
  67.   opcode = exp->elts[pc].opcode;
  68.   switch (opcode)
  69.     {
  70.     /* Common ops */
  71.  
  72.     case OP_SCOPE:
  73.       myprec = PREC_PREFIX;
  74.       assoc = 0;
  75.       (*pos) += 2;
  76.       print_subexp (exp, pos, stream,
  77.             (enum precedence) ((int) myprec + assoc));
  78.       fputs_filtered (" :: ", stream);
  79.       nargs = strlen (&exp->elts[pc + 2].string);
  80.       (*pos) += 1 + (nargs + sizeof (union exp_element)) / sizeof (union exp_element);
  81.  
  82.       fputs_filtered (&exp->elts[pc + 2].string, stream);
  83.       return;
  84.  
  85.     case OP_LONG:
  86.       (*pos) += 3;
  87.       value_print (value_from_longest (exp->elts[pc + 1].type,
  88.                     exp->elts[pc + 2].longconst),
  89.            stream, 0, Val_no_prettyprint);
  90.       return;
  91.  
  92.     case OP_DOUBLE:
  93.       (*pos) += 3;
  94.       value_print (value_from_double (exp->elts[pc + 1].type,
  95.                       exp->elts[pc + 2].doubleconst),
  96.            stream, 0, Val_no_prettyprint);
  97.       return;
  98.  
  99.     case OP_VAR_VALUE:
  100.       (*pos) += 2;
  101.       fputs_filtered (SYMBOL_NAME (exp->elts[pc + 1].symbol), stream);
  102.       return;
  103.  
  104.     case OP_LAST:
  105.       (*pos) += 2;
  106.       fprintf_filtered (stream, "$%d",
  107.             longest_to_int (exp->elts[pc + 1].longconst));
  108.       return;
  109.  
  110.     case OP_REGISTER:
  111.       (*pos) += 2;
  112.       fprintf_filtered (stream, "$%s",
  113.            longest_to_int (reg_names[exp->elts[pc + 1].longconst]));
  114.       return;
  115.  
  116.     case OP_INTERNALVAR:
  117.       (*pos) += 2;
  118.       fprintf_filtered (stream, "$%s",
  119.            internalvar_name (exp->elts[pc + 1].internalvar));
  120.       return;
  121.  
  122.     case OP_FUNCALL:
  123.       (*pos) += 2;
  124.       nargs = longest_to_int (exp->elts[pc + 1].longconst);
  125.       print_subexp (exp, pos, stream, PREC_SUFFIX);
  126.       fputs_filtered (" (", stream);
  127.       for (tem = 0; tem < nargs; tem++)
  128.     {
  129.       if (tem != 0)
  130.         fputs_filtered (", ", stream);
  131.       print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
  132.     }
  133.       fputs_filtered (")", stream);
  134.       return;
  135.  
  136.     case OP_STRING:
  137.       nargs = strlen (&exp->elts[pc + 1].string);
  138.       (*pos) += 2 + (nargs + sizeof (union exp_element)) / sizeof (union exp_element);
  139.       fputs_filtered ("\"", stream);
  140.       for (tem = 0; tem < nargs; tem++)
  141.     printchar ((&exp->elts[pc + 1].string)[tem], stream, '"');
  142.       fputs_filtered ("\"", stream);
  143.       return;
  144.  
  145.     case TERNOP_COND:
  146.       if ((int) prec > (int) PREC_COMMA)
  147.     fputs_filtered ("(", stream);
  148.       /* Print the subexpressions, forcing parentheses
  149.      around any binary operations within them.
  150.      This is more parentheses than are strictly necessary,
  151.      but it looks clearer.  */
  152.       print_subexp (exp, pos, stream, PREC_HYPER);
  153.       fputs_filtered (" ? ", stream);
  154.       print_subexp (exp, pos, stream, PREC_HYPER);
  155.       fputs_filtered (" : ", stream);
  156.       print_subexp (exp, pos, stream, PREC_HYPER);
  157.       if ((int) prec > (int) PREC_COMMA)
  158.     fputs_filtered (")", stream);
  159.       return;
  160.  
  161.     case STRUCTOP_STRUCT:
  162.       tem = strlen (&exp->elts[pc + 1].string);
  163.       (*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element);
  164.       print_subexp (exp, pos, stream, PREC_SUFFIX);
  165.       fputs_filtered (".", stream);
  166.       fputs_filtered (&exp->elts[pc + 1].string, stream);
  167.       return;
  168.  
  169.     /* Will not occur for Modula-2 */
  170.     case STRUCTOP_PTR:
  171.       tem = strlen (&exp->elts[pc + 1].string);
  172.       (*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element);
  173.       print_subexp (exp, pos, stream, PREC_SUFFIX);
  174.       fputs_filtered ("->", stream);
  175.       fputs_filtered (&exp->elts[pc + 1].string, stream);
  176.       return;
  177.  
  178.     case BINOP_SUBSCRIPT:
  179.       print_subexp (exp, pos, stream, PREC_SUFFIX);
  180.       fputs_filtered ("[", stream);
  181.       print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
  182.       fputs_filtered ("]", stream);
  183.       return;
  184.  
  185.     case UNOP_POSTINCREMENT:
  186.       print_subexp (exp, pos, stream, PREC_SUFFIX);
  187.       fputs_filtered ("++", stream);
  188.       return;
  189.  
  190.     case UNOP_POSTDECREMENT:
  191.       print_subexp (exp, pos, stream, PREC_SUFFIX);
  192.       fputs_filtered ("--", stream);
  193.       return;
  194.  
  195.     case UNOP_CAST:
  196.       (*pos) += 2;
  197.       if ((int) prec > (int) PREC_PREFIX)
  198.         fputs_filtered ("(", stream);
  199.       fputs_filtered ("(", stream);
  200.       type_print (exp->elts[pc + 1].type, "", stream, 0);
  201.       fputs_filtered (") ", stream);
  202.       print_subexp (exp, pos, stream, PREC_PREFIX);
  203.       if ((int) prec > (int) PREC_PREFIX)
  204.         fputs_filtered (")", stream);
  205.       return;
  206.  
  207.     case UNOP_MEMVAL:
  208.       (*pos) += 2;
  209.       if ((int) prec > (int) PREC_PREFIX)
  210.         fputs_filtered ("(", stream);
  211.       if (exp->elts[pc + 1].type->code == TYPE_CODE_FUNC &&
  212.       exp->elts[pc + 3].opcode == OP_LONG) {
  213.     /* We have a misc function vector fn, probably.  It's encoded
  214.        as a UNOP_MEMVAL (function-type) of an OP_LONG (int, address).
  215.        Swallow the OP_LONG (including both its opcodes); ignore
  216.        its type; print the value in the type of the MEMVAL.  */
  217.     (*pos) += 4;
  218.     val = value_at_lazy (exp->elts[pc + 1].type,
  219.                  exp->elts[pc + 5].longconst);
  220.     value_print (val, stream, 0, Val_no_prettyprint);
  221.       } else {
  222.     fputs_filtered ("{", stream);
  223.     type_print (exp->elts[pc + 1].type, "", stream, 0);
  224.     fputs_filtered ("} ", stream);
  225.         print_subexp (exp, pos, stream, PREC_PREFIX);
  226.       }
  227.       if ((int) prec > (int) PREC_PREFIX)
  228.         fputs_filtered (")", stream);
  229.       return;
  230.  
  231.     case BINOP_ASSIGN_MODIFY:
  232.       opcode = exp->elts[pc + 1].opcode;
  233.       (*pos) += 2;
  234.       myprec = PREC_ASSIGN;
  235.       assoc = 1;
  236.       assign_modify = 1;
  237.       op_str = "???";
  238.       for (tem = 0; op_print_tab[tem].opcode != OP_NULL; tem++)
  239.     if (op_print_tab[tem].opcode == opcode)
  240.       {
  241.         op_str = op_print_tab[tem].string;
  242.         break;
  243.       }
  244.       break;
  245.  
  246.     /* C++ ops */
  247.  
  248.     case OP_THIS:
  249.       ++(*pos);
  250.       fputs_filtered ("this", stream);
  251.       return;
  252.  
  253.     /* Modula-2 ops */
  254.  
  255.     case BINOP_MULTI_SUBSCRIPT:
  256.       (*pos) += 2;
  257.       nargs = longest_to_int (exp->elts[pc + 1].longconst);
  258.       print_subexp (exp, pos, stream, PREC_SUFFIX);
  259.       fprintf (stream, " [");
  260.       for (tem = 0; tem < nargs; tem++)
  261.     {
  262.       if (tem != 0)
  263.         fprintf (stream, ", ");
  264.       print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
  265.     }
  266.       fprintf (stream, "]");
  267.       return;
  268.  
  269.     case BINOP_VAL:
  270.       (*pos)+=2;
  271.       fprintf(stream,"VAL(");
  272.       type_print(exp->elts[pc+1].type,"",stream,0);
  273.       fprintf(stream,",");
  274.       print_subexp(exp,pos,stream,PREC_PREFIX);
  275.       fprintf(stream,")");
  276.       return;
  277.  
  278.     case UNOP_CAP:
  279.       print_simple_m2_func("CAP",exp,pos,stream);
  280.       return;
  281.  
  282.     case UNOP_CHR:
  283.       print_simple_m2_func("CHR",exp,pos,stream);
  284.       return;
  285.  
  286.     case UNOP_ORD:
  287.       print_simple_m2_func("ORD",exp,pos,stream);
  288.       return;
  289.       
  290.     case UNOP_ABS:
  291.       print_simple_m2_func("ABS",exp,pos,stream);
  292.       return;
  293.  
  294.     case UNOP_FLOAT:
  295.       print_simple_m2_func("FLOAT",exp,pos,stream);
  296.       return;
  297.  
  298.     case UNOP_HIGH:
  299.       print_simple_m2_func("HIGH",exp,pos,stream);
  300.       return;
  301.  
  302.     case UNOP_MAX:
  303.       print_simple_m2_func("MAX",exp,pos,stream);
  304.       return;
  305.  
  306.     case UNOP_MIN:
  307.       print_simple_m2_func("MIN",exp,pos,stream);
  308.       return;
  309.  
  310.     case UNOP_ODD:
  311.       print_simple_m2_func("ODD",exp,pos,stream);
  312.       return;
  313.  
  314.     case UNOP_TRUNC:
  315.       print_simple_m2_func("TRUNC",exp,pos,stream);
  316.       return;
  317.       
  318.     case BINOP_INCL:
  319.     case BINOP_EXCL:
  320.       error("print_subexp:  Not implemented.");
  321.  
  322.     /* Default ops */
  323.  
  324.     default:
  325.       op_str = "???";
  326.       for (tem = 0; op_print_tab[tem].opcode != OP_NULL; tem++)
  327.     if (op_print_tab[tem].opcode == opcode)
  328.       {
  329.         op_str = op_print_tab[tem].string;
  330.         myprec = op_print_tab[tem].precedence;
  331.         assoc = op_print_tab[tem].right_assoc;
  332.         break;
  333.       }
  334.    }
  335.  
  336.   if ((int) myprec < (int) prec)
  337.     fputs_filtered ("(", stream);
  338.   if ((int) opcode > (int) BINOP_END)
  339.     {
  340.       /* Unary prefix operator.  */
  341.       fputs_filtered (op_str, stream);
  342.       print_subexp (exp, pos, stream, PREC_PREFIX);
  343.     }
  344.   else
  345.     {
  346.       /* Binary operator.  */
  347.       /* Print left operand.
  348.      If operator is right-associative,
  349.      increment precedence for this operand.  */
  350.       print_subexp (exp, pos, stream,
  351.             (enum precedence) ((int) myprec + assoc));
  352.       /* Print the operator itself.  */
  353.       if (assign_modify)
  354.     fprintf_filtered (stream, " %s= ", op_str);
  355.       else if (op_str[0] == ',')
  356.     fprintf_filtered (stream, "%s ", op_str);
  357.       else
  358.     fprintf_filtered (stream, " %s ", op_str);
  359.       /* Print right operand.
  360.      If operator is left-associative,
  361.      increment precedence for this operand.  */
  362.       print_subexp (exp, pos, stream,
  363.             (enum precedence) ((int) myprec + !assoc));
  364.     }
  365.  
  366.   if ((int) myprec < (int) prec)
  367.     fputs_filtered (")", stream);
  368. }
  369.  
  370. /* Print out something of the form <s>(<arg>).
  371.    This is used to print out some builtin Modula-2
  372.    functions.
  373.    FIXME:  There is probably some way to get the precedence
  374.    rules to do this (print a unary operand with parens around it).  */
  375. static void
  376. print_simple_m2_func(s,exp,pos,stream)
  377.    char *s;
  378.    register struct expression *exp;
  379.    register int *pos;
  380.    FILE *stream;
  381. {
  382.    fprintf(stream,"%s(",s);
  383.    print_subexp(exp,pos,stream,PREC_PREFIX);
  384.    fprintf(stream,")");
  385. }
  386.    
  387. /* Return the operator corresponding to opcode OP as
  388.    a string.   NULL indicates that the opcode was not found in the
  389.    current language table.  */
  390. char *
  391. op_string(op)
  392.    enum exp_opcode op;
  393. {
  394.   int tem;
  395.   register const struct op_print *op_print_tab;
  396.  
  397.   op_print_tab = current_language->la_op_print_tab;
  398.   for (tem = 0; op_print_tab[tem].opcode != OP_NULL; tem++)
  399.     if (op_print_tab[tem].opcode == op)
  400.       return op_print_tab[tem].string;
  401.   return NULL;
  402. }
  403.